package com.xiaoq.jobs;

import com.xiaoq.apis.user.IPushMessageApi;
import com.xiaoq.positionmarket.entity.PositionMarketEntity;
import com.xiaoq.positionmarket.entity.PositionPushRecordEntity;
import com.xiaoq.positionmarket.service.IPositionMarketService;
import com.xiaoq.positionmarket.service.IPositionPushRecordService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.quartz.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.quartz.QuartzJobBean;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by chenjh on 2018/4/4.
 */
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
public class PositionMarketJob extends QuartzJobBean {

    private static Logger LOGGER = LoggerFactory.getLogger(PositionMarketJob.class);

    public static final String POSITION_MARK_ID = "positionMarketId";
    public static final String PUSH_BY_TYPE = "key";
    public static final String PUSH_BY_CITY = "city";
    public static final String PUSH_BY_LOCATION = "location";

    private static final ExecutorService executorService = Executors.newFixedThreadPool(4);


    /**
     * PositionMarketJob 为反射创建， 因此 添加@Autowired 注解后
     * pushMessageApi 依然不能注入，需从 ApplicationContext 里取
     *    见executeInternal(JobExecutionContext context)
     */
    private IPushMessageApi pushMessageApi; //不能注入 ，为 null


    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {

        ApplicationContext applicationContext;
        try {
            applicationContext = (ApplicationContext) context.getScheduler().getContext().get("applicationContext");
        }catch (Exception e){
            LOGGER.error(e.getMessage());
            return;
        }

        if(applicationContext == null){
            LOGGER.error("*****获取定时任务applicationContext失败******");
            return;
        }

        ServiceBeanApiConfig serviceBeanApiConfig = applicationContext.getBean(ServiceBeanApiConfig.class);
        IPositionPushRecordService pushRecordService = serviceBeanApiConfig.getPositionPushRecordService();
        pushMessageApi = serviceBeanApiConfig.getPushMessageApi();
        IPositionMarketService positionMarketService = serviceBeanApiConfig.getPositionMarketService();

        JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
        String positionMarketId = jobDataMap.getString(POSITION_MARK_ID);
        String pushByType = jobDataMap.getString(PUSH_BY_TYPE);

        PositionMarketEntity positionMarketEntity = positionMarketService.getById(positionMarketId);
        List<PositionPushRecordEntity> pushRecordList = pushRecordService.getListByPositionMarketId(positionMarketId);

        if(CollectionUtils.isNotEmpty(pushRecordList) && positionMarketEntity != null){
            if(PUSH_BY_CITY.equals(pushByType)){
                //处理通过城市推送
                Set<String> userIdSet = new HashSet<>();
                for (PositionPushRecordEntity positionPushRecordEntity : pushRecordList){
                    userIdSet.add(positionPushRecordEntity.getUserId());
                }

                String title = positionMarketEntity.getTitle();
                String tmpSelectId = positionMarketEntity.getSelectId();
                String selectType = positionMarketEntity.getSelectType() + "";
                String selectTitle = positionMarketEntity.getSelectTitle();
                List<String> userIdList = new ArrayList<>(userIdSet);
                String selectImgUrl = positionMarketEntity.getSelectImgUrl();

                //因为APP端是根据景区id获取优惠券列表的。。。
//                if("7".equals(selectType)){
//                    tmpSelectId = positionMarketEntity.getShopId();
//                }

                final String selectId = tmpSelectId;
                for (String userId : userIdList){
                    try {
                        executorService.execute(() -> {
                            pushMessageApi.sendMessageWithImag(userId,
                                    "3",
                                    title,
                                    selectTitle,
                                    selectId,
                                    selectType,
                                    null, selectImgUrl, true);
                        });
                    }catch (Exception e){
                        LOGGER.error(e.getMessage());
                    }
                }

            }else if(PUSH_BY_LOCATION.equals(pushByType)){ //处理通过距离推送
                //去重
                Set<String> regId4iOSSet = new HashSet<>();
                Set<String> regId4AndroidSet = new HashSet<>();
                for (PositionPushRecordEntity pushRecordEntity : pushRecordList){
                    String osType = StringUtils.defaultIfEmpty(pushRecordEntity.getOsType(), "");
                    if("iOS".equalsIgnoreCase(osType)){
                        regId4iOSSet.add(pushRecordEntity.getRegId());
                    }else if ("Android".equalsIgnoreCase(osType)){
                        regId4AndroidSet.add(pushRecordEntity.getRegId());
                    }
                }

                List<String> regId4iOSList = new ArrayList<>(regId4iOSSet);
                List<String> regId4AndroidList = new ArrayList<>(regId4AndroidSet);
                //推送
                sendMessage(regId4iOSList, positionMarketEntity, true);
                sendMessage(regId4AndroidList, positionMarketEntity, false);
            }
        }

        executorService.shutdown();
        //更新撒时间推送的
        PositionMarketEntity updatePositionMarket = new PositionMarketEntity();
        updatePositionMarket.setId(positionMarketId);
        updatePositionMarket.setTriggerRealTime(System.currentTimeMillis());
        positionMarketService.updateById(updatePositionMarket);
    }



    private void sendMessage(List<String> regIdList, PositionMarketEntity positionMarketEntity, boolean isIOS){
        if(CollectionUtils.isEmpty(regIdList)){
            return;
        }

        String title = positionMarketEntity.getTitle();
        String selectId = positionMarketEntity.getSelectId();
        String selectType = positionMarketEntity.getSelectType() + "";
        String selectImgUrl = positionMarketEntity.getSelectImgUrl();
        String selectTitle = positionMarketEntity.getSelectTitle();

        //因为APP端是根据景区id获取优惠券列表的。。。
//        if("7".equals(selectType)){
//            selectId = positionMarketEntity.getShopId();
//        }

        long regIdListSize = regIdList.size();

        if(regIdListSize > 100){
            List<String> tmpRegIdList = new ArrayList<>();
            for (int i = 1; i < regIdListSize+1; i++) {
                if(i % 100 != 0){
                    tmpRegIdList.add(regIdList.get(i-1));
                }else {
                    //推送
                    executorService.execute(new PositionPushThread(tmpRegIdList, selectId, selectTitle, title, selectType, selectImgUrl, isIOS));
                    tmpRegIdList = new ArrayList<>();
                }
            }

            if(tmpRegIdList.size() > 0){
                executorService.execute(new PositionPushThread(tmpRegIdList, selectId,selectTitle, title, selectType, selectImgUrl, isIOS));
            }

        }else {
            executorService.execute(new PositionPushThread(regIdList, selectId, selectTitle, title, selectType, selectImgUrl, isIOS));
        }

    }




    /**
     * mesTarId    消息对物体的详细Id(票Id,优惠券Id等
       mesType    消息对象的具体类别（1系统消息，2,门票订单，3，讲解员订单，4，优惠劵过期，5活动海报，6旅行头条，7优惠券详情）
     */
    private class PositionPushThread implements Runnable{

        private List<String> regIdList;
        private boolean isIOS;
        private String selectTitle;
        private String selectId;
        private String selectType;
        private String imgUrl;
        private String title;

        public PositionPushThread(List<String> regIdList, String selectId, String selectTitle, String title, String selectType, String imgUrl, boolean isIOS) {
            this.regIdList = regIdList;
            this.selectId = selectId;
            this.selectTitle = selectTitle;
            this.selectType = selectType;
            this.isIOS = isIOS;
            this.imgUrl = imgUrl;
            this.title = title;
        }

        @Override
        public void run() {

            if(CollectionUtils.isEmpty(regIdList)){
                return;
            }

          try {
                if(isIOS){
                    pushMessageApi.sendMessageToIOSUsers(regIdList,
                            "3",
                            title,
                            selectTitle,
                            selectId,
                            selectType,
                            "23423", imgUrl, true);
                }else {
                    pushMessageApi.sendMessageToAndroidUsers(regIdList,
                            "3",
                            title,
                            selectTitle,
                            selectId,
                            selectType,
                            "23423");
                }
            }catch (Exception e){
                LOGGER.error(e.getMessage());
            }
        }
    }
}

